#ifndef classes_hpp
#define classes_hpp

#include <iostream>
#include <string>

#include <cstring>
#include <ctime>
#include <cstdlib>

using namespace std;

// --------------- HUMAIN ------------------

class humain{
 private:
  char* nom;
  string boisson;
  int argent;
 public:
  humain();
  humain(const char* n, string b);
  humain(const char* n, int a);
  humain(const char* n, int a, string b);
  humain(const humain &h);
 
  char* get_nom() const;
  string get_boisson () const;
  int get_argent() const;
  void set_nom(char* n);
  void set_boisson(string b);
  void set_argent (int a);

  humain & operator =( const humain &h);
  friend ostream & operator<<(ostream &s, const humain &h);
  virtual void affiche(ostream &s) const;
  virtual void dire_bonjour() const;
  void parler(string discours) const ;
  void boire() const;
  void perdre_argent(int x);
  void gagner_argent(int x);
  virtual ~humain();

  virtual void donner(int a,  humain *h)=0;
  virtual void action( humain *h)=0;

 
};

/*

---------------- COMMERCANT  ----------------------

*/

class commercant: public humain{
 public:
  commercant(const char* n, int a);
  commercant(const commercant &c);
  void se_faire_extorquer();
  void recevoir_argent(int a);
  commercant & operator =( const commercant &c);
  void donner(int a,  humain *h );
  void action( humain *h );
  void dire_bonjour()const;
 };

// ----------------- YAKUZA --------------------

class yakuza: public humain{
 private:
  string clan;
  int reputation;
 public:
  yakuza(const char* n, int a, string b, int rep, string c);
  yakuza(const char* n, int a, string b, string c);
  void extorquer( commercant &c);
  ~yakuza();
  string get_clan()const;
  int get_reputation()const;
  void set_clan(string nouveau_clan);
  void set_reputation(int nouvelle_reput);
  void affiche(ostream &s) const;
  void gagner();
  void perdre(); // pourquoi faire un int ? retourne l'argent qu'il a perdu ?
  yakuza & operator=(const yakuza &y);
  void dire_bonjour() const;
  void donner( int a, humain *h );
  void action( humain *h );
};

// ------------------- RONIN ------------------------

class ronin: public humain{
 private :
  int honneur;
 public:
  ronin(const char *n, int a, string b, int h);
  ronin(const char *n, int a, string b);
  void donner(int argent, commercant &c);
  void provoquer(yakuza &y);
  virtual void affiche( ostream &s)const;
  int get_honneur() const;
  void set_honneur(int h);
  ronin & operator =( const ronin &r);
  ~ronin();
  virtual void dire_bonjour() const;
  void donner(int a,  humain *h );
  void action( humain *h );
};

// -------------------- SAMURAI ----------------------  

class samurai: public ronin{
 private :
  string seigneur;
 public:
  samurai(const char* n, int a, string b, int h, string s);
  samurai(const char *n, int a, string b,  string s);
  void boire(string b) const;
  void affiche(ostream &s)const;
  string get_seigneur() const;
  void set_seigneur(string s);
  samurai & operator =( const samurai &s);
  ~samurai();
  void dire_bonjour() const;
  void donner( int a, humain *h );
  void action( humain *h );
};


// -------------------- GRILLE ----------------------  

#define taille 5

class grille {
private:
  humain *planet[taille][taille];
public:
  grille() { 
    srand(time(NULL));
    for (int i=0; i<taille; i++)
      for (int j=0; j<taille;j++)
	planet[i][j]=0;
    
    int rd=0;
    int nb_case_vide=taille*taille;
    while(nb_case_vide > ((taille*taille)*(2./3))) {
      rd = rand() %4;
      placer(rd);
      nb_case_vide --;
    }
  }
  void placer(int k);
  void say_hello() const;
  ~grille();
  void affiche_grille();
  void modif_grille();
  void move_left(int i, int j);
  void move_right(int i, int j);
  void move_up(int i, int j);
  void move_down(int i, int j);
  void rd_move(int i, int j);
  
};


#endif
